package com.codequirks.xmlbeanutils;

import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * This class is provided to interact with legacy parsers that do not properly
 * implement methods such as "getTextContent()". It provides alternate
 * means of accessing these properties that should avoid.
 * <p/>
 * If you are experiencing "AbstractMethodException" while using XmlDynaBean,
 * consider trying one of these.
 * <p/>
 * Old versions of Xerces have been known to cause this behaviour.
 *
 * @author Travis Calder <travis.calder@gmail.com>
 * @since 1.0.1
 */
public class LegacyNodePropertyAccessor implements NodePropertyAccessor {

    @Override
    public NodeList getAllChildren(Node node) {
        return node.getChildNodes();
    }

    @Override
    public NamedNodeMap getAllAttributes(Node node) {
        return node.getAttributes();
    }

    @Override
    public String getNodeName(Node node) {
        return node.getNodeName();
    }

    /**
     * Retrieves the text content of a node without using the "getTextContent" method.
     *
     * @param attribute Attribute to retrieve the value from
     * @return The value of the attribute 
     */
    public String getAttributeContents(Attr attribute) {
        return attribute.getFirstChild().getNodeValue();
    }

    /**
     * Retrieves the text content of a node without using the "getTextContent" method.
     *
     * This is accomplished by moving through the nodes, and appending the node value
     * of any <code>Node.TEXT_NODE</code> found along the way
     *
     * @param node Node to parse.
     * @return Content of each TEXT_NODE, concatenated together.
     * @see Node
     */
    @Override
    public String getNodeText(Node node) {
        String result = "";
        Node child = node.getFirstChild();
        do {
            if (child.getNodeType() == Node.TEXT_NODE) {
                result += child.getNodeValue();
            }
        } while ((child = child.getNextSibling()) != null);
        return result;
    }
}
